package com.bw.net

import android.content.Intent
import android.os.Build
import androidx.localbroadcastmanager.content.LocalBroadcastManager
import com.bw.common.BaseApplication
import com.bw.common.encry.AESUtils
import com.bw.common.utils.SharedPreferenceDelegate
import com.bw.net.common.ConstantValue
import okhttp3.Interceptor
import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import java.util.concurrent.TimeUnit

/**
 * @author:created by hahajing
 * 时间：2024/4/23 0023
 * 企鹅号:444511958
 * 描述:
 */
object RetrofitUtils {
    private val retrofit: Retrofit

    init {
        retrofit = generateRetrofitInstance()
    }

    /**
     * 通过retrofit 接口生成实例
     */
    fun <T> create(target:Class<*>):T{
        return retrofit.create(target) as T
    }

    /**
     * 创建Retrofit实例方法
     */
    private fun generateRetrofitInstance(): Retrofit {

        //使用建造者设计模式（持续构建一个复杂对象）（创建型设计模式）创建retrofit实例对象
        return Retrofit.Builder()
            .baseUrl(BuildConfig.SERVER_HOST)
            .addConverterFactory(GsonConverterFactory.create())
            .client(generateOkHttpClient())
            .build()
    }

    /**
     * 创建Okhttp对象实例
     */
    private fun generateOkHttpClient(): OkHttpClient {

        val builder = OkHttpClient.Builder()
            .retryOnConnectionFailure(true)

        if (BuildConfig.DEBUG) {
            builder.addNetworkInterceptor(HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY))
        }

        return builder.addInterceptor(generateTokenInterceptor())
            .addInterceptor(generatePublicPamamsInterceptor())
            .connectTimeout(ConstantValue.TIMEOUT,TimeUnit.SECONDS)
            .readTimeout(ConstantValue.TIMEOUT,TimeUnit.SECONDS)
            .writeTimeout(ConstantValue.TIMEOUT,TimeUnit.SECONDS)
            .callTimeout(ConstantValue.TIMEOUT,TimeUnit.SECONDS)
//            .cache(null)
            .build()
    }

    //?product=huawei&model=rongyao7plus&display=1280*1920&cpu=armv8a

    /**
     * 添加公共参数
     */
    private fun generatePublicPamamsInterceptor(): Interceptor {
        return Interceptor {
            val request = it.request()
            val newUrl = request.url.newBuilder()
                .addQueryParameter("proudct",Build.BRAND)
                .addQueryParameter("model",Build.MODEL)
                .build()
            val newRequest = request.newBuilder()
                .url(newUrl)
                .build()
            it.proceed(newRequest)
        }
    }

    private var token:String by SharedPreferenceDelegate<String>(BaseApplication.getApplicationContext(),com.bw.common.common.ConstantValue.SP_NAME,com.bw.common.common.ConstantValue.SP_KEY_TOKEN,"")

    /**
     * 添加token处理
     */
    private fun generateTokenInterceptor(): Interceptor {
        return Interceptor {
            val request = it.request()
            if (!token.isEmpty()){
                val finalToken = AESUtils.getInstance().decrypt(token,ConstantValue.AESKEY)
                val newRequest = request.newBuilder()
                    .addHeader("token",finalToken)
                    .build()

                return@Interceptor it.proceed(newRequest)
            }
            val response = it.proceed(request)
            when(response.code){
                401->{
                    sendLocalBroadcast(com.bw.common.common.ConstantValue.NET_ERR_401)
                }
                500->{
                    sendLocalBroadcast(com.bw.common.common.ConstantValue.NET_ERR_500)
                }
                404->{
                    sendLocalBroadcast(com.bw.common.common.ConstantValue.NET_ERR_404)
                }
                403->{
                    sendLocalBroadcast(com.bw.common.common.ConstantValue.NET_ERR_403)
                }
            }

            response
        }
    }

    private fun sendLocalBroadcast(action:String){
        val intent = Intent()
        intent.setAction(action)
        LocalBroadcastManager.getInstance(BaseApplication.getApplicationContext()).sendBroadcast(intent)
    }
}